package com.channel.temperature.collect.ui.viewmodel

import android.content.res.Configuration
import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.hjq.toast.ToastUtils
import com.hjy.bluetooth.HBluetooth
import com.hjy.bluetooth.exception.BluetoothException
import com.hjy.bluetooth.inter.SendCallBack
import com.hjy.bluetooth.operator.abstra.Sender
import com.kongzue.dialogx.dialogs.MessageDialog
import com.kongzue.dialogx.interfaces.OnDialogButtonClickListener
import com.channel.temperature.collect.R
import com.channel.temperature.collect.app.ext.LiveDataEvent
import com.channel.temperature.collect.app.ext.mmkv
import com.channel.temperature.collect.app.util.CRC16Utils
import com.channel.temperature.collect.app.util.MyUtil
import com.channel.temperature.collect.data.annotation.ValueKey
import com.channel.temperature.collect.data.response.AppUpdateBean
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withTimeoutOrNull
import me.hgj.mvvmhelper.base.BaseViewModel
import me.hgj.mvvmhelper.base.appContext
import rxhttp.toAwait
import rxhttp.wrapper.param.RxHttp
import java.text.SimpleDateFormat
import java.util.Date


class SettingModel : BaseViewModel() {
    var checkTimeCMDSendTime = ""
    var clickType = 0
    var packageDataLength: Int = 0
    var resultDataLength: Int = 0
    var needFoldData = false
    var dataResult: ByteArray = ByteArray(215)
    var otherPackageData = ByteArray(80)
    var checkedWorkMode = 0 //0:空闲模式 1：离线模式 3：在线模式
    var closeWaitDialog = MutableLiveData<Boolean>()
    var taskDeviceName = ""
    var taskCurrentName: ByteArray = ByteArray(40)
    var taskDesc: ByteArray = ByteArray(40)
    var showPopupwindow = MutableLiveData<Boolean>()
    var setedDeviceName = ""
    var clearFlashIndex = 0
    var continueClear = MutableLiveData<Boolean>()
    var mAppUpdateEntity = MutableLiveData<AppUpdateBean>()
    fun handleBLEResult(data: ByteArray) {
        Log.e("handleBLEResult", "handleBLEResult " + MyUtil.bytes2Hex(data))
        if (data.size > 2) {
            when (clickType) {
                //先查系统参数的工作模式是不是3
                //5:校时
                9 -> {
                    var hexResult = MyUtil.bytes2Hex(data.copyOfRange(0, 3))
                    viewModelScope.launch {
                        if ("FF55AA" == hexResult) {
                            packageDataLength = 0
                            resultDataLength = MyUtil.bytes2Hex(data.copyOfRange(3, 5)).toInt(16)
                            dataResult = ByteArray(resultDataLength + 5)
                            needFoldData = data.size < resultDataLength + 5
                        }
                        if (needFoldData) {
                            System.arraycopy(data, 0, dataResult, packageDataLength, data.size)
                            packageDataLength += data.size
                            needFoldData = packageDataLength != resultDataLength + 5
                            if (packageDataLength == resultDataLength + 5) {
                                var packageData = dataResult.copyOfRange(0, dataResult.size - 1)
                                var result = CRC16Utils.checkCRC(packageData)

                                if (result.toInt(16) == java.lang.Byte.toUnsignedInt(dataResult[dataResult.size - 1])) {
                                    handleWorkMode(dataResult)
                                } else {
                                    ToastUtils.show("命令校验失败")


                                }

                            }
                        } else {
                            var packageData = data.copyOfRange(0, data.size - 1)
                            var result = CRC16Utils.checkCRC(packageData)
                            if (result.toInt(16) == java.lang.Byte.toUnsignedInt(data[data.size - 1])) {
                                handleWorkMode(data)
                            } else {
                                ToastUtils.show("命令校验失败")
                            }
                        }

                    }
                }

                21 -> {
                    viewModelScope.launch {
                        var hexResult = MyUtil.bytes2Hex(data.copyOfRange(0, 3))
                        var packageData = data.copyOfRange(0, data.size - 1)
                        var result = CRC16Utils.checkCRC(packageData)
                        if ("FF55AA" == hexResult && result.toInt(16) == java.lang.Byte.toUnsignedInt(
                                data[data.size - 1]
                            )
                        ) {
                            var collectCount = MyUtil.bytesToInt(data.copyOfRange(9, 13)).toLong()
                            var usedBattery =
                                MyUtil.bytes2FloatOther(data.copyOfRange(13, 17)).toFloat()
                            var totalBattery =
                                MyUtil.bytes2FloatOther(data.copyOfRange(17, 21)).toFloat()
                            Log.e("测试", "测试  " + usedBattery + "     " + totalBattery)
                            var leftBattery = totalBattery - usedBattery
                            var leftPercent = MyUtil.formatFloat(
                                (totalBattery - usedBattery) / totalBattery * 100, 3, 0.00f
                            )
                            MessageDialog.show(
                                "提示", "剩余电量:$leftPercent" + "%", "确定"
                            ).maxWidth =
                                if (appContext.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) appContext.resources.displayMetrics.widthPixels / 2 else appContext.resources.displayMetrics.widthPixels
                            resetClickType()
                        }
                    }
                }

                10 -> {
                    viewModelScope.launch {
                        var hexResult = MyUtil.bytes2Hex(data.copyOfRange(0, 3))
                        var dataHex = MyUtil.bytes2Hex(data)
                        if ("FF55AA" == hexResult && dataHex.substring(14, 16).toInt(16) == 2) {
                            ToastUtils.show("设置系统模式成功")
                            LiveDataEvent.currentMode.value = checkedWorkMode
                            LiveDataEvent.notifyReReadSystemInfo.value = true
                            resetClickType()
                        }
                    }

                }

                31 -> {
//                addMessage("读取数据成功 ：" + MyUtil.bytes2Hex(data))
                    var time = formatTimeString(MyUtil.bytes2Hex(data.copyOfRange(7, 13)))
                    val messageDialog = MessageDialog.show(
                        "提示",
                        "设备当前时间:$time" + "\n" + "终端当前时间:${MyUtil.DateToStr(Date())}",
                        "确认校时",
                        "取消"
                    )
                    if (appContext.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
                        messageDialog.setMaxWidth(appContext.resources.displayMetrics.widthPixels / 2)
                    }
                    messageDialog.okButtonClickListener = OnDialogButtonClickListener { dialog, v ->
                        dialog.dismiss()
                        if (HBluetooth.getInstance().isConnected) {
                            HBluetooth.getInstance().sender()?.let { it1 ->
                                var date = Date()
                                val format = SimpleDateFormat("yyMMddHHmmss")
                                val str = format.format(date)
                                Log.e("校时", "校时str  " + str)
                                var year = MyUtil.numberToHexOne(str.substring(0, 2).toInt())
                                var month = MyUtil.numberToHexOne(str.substring(2, 4).toInt())
                                var day = MyUtil.numberToHexOne(str.substring(4, 6).toInt())
                                var hour = MyUtil.numberToHexOne(str.substring(6, 8).toInt())
                                var minute = MyUtil.numberToHexOne(str.substring(8, 10).toInt())
                                var second = MyUtil.numberToHexOne(str.substring(10, 12).toInt())
                                var time = "" + year + month + day + hour + minute + second
                                Log.e("校时", "校时1111111    " + time)
                                clickType = 5
                                checkTimeCMDSendTime = time
                                var cmd = "FF55AA000A" + getAddress() + "4202$time"
                                sendCommonCMD(
                                    it1, cmd + CRC16Utils.checkCRC(MyUtil.hex2Bytes(cmd))
                                )
                            }
                        } else {
                            ToastUtils.show("请先连接设备后再操作")
                        }
                        true
                    }
                    resetClickType()
                }

                5 -> {
                    var dataHex = MyUtil.bytes2Hex(data)
                    var time = formatTimeString(MyUtil.bytes2Hex(data.copyOfRange(7, 13)))
                    var timeLong = MyUtil.StrToDate(time).time
                    Log.e("设备当前时间", "  " + timeLong)
                    var currentTime = System.currentTimeMillis()
                    Log.e("手机当前时间", "  " + currentTime)
                    var minusResult = (currentTime - timeLong) / 1000
                    Log.e("相差毫秒数", "  " + minusResult)
                    if (minusResult >= -30 && minusResult <= 30) {
                        MessageDialog.show(
                            "提示", "校时成功", "确定"
                        ).maxWidth =
                            if (appContext.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) appContext.resources.displayMetrics.widthPixels / 2 else appContext.resources.displayMetrics.widthPixels
                    } else {
                        MessageDialog.show(
                            "提示", "校时失败", "确定"
                        ).maxWidth =
                            if (appContext.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) appContext.resources.displayMetrics.widthPixels / 2 else appContext.resources.displayMetrics.widthPixels
                    }
                    resetClickType()
                }

                11 -> {
//                addMessage("读取数据成功 ：" + MyUtil.bytes2Hex(data))
                    var time = formatTimeString(MyUtil.bytes2Hex(data.copyOfRange(7, 13)))
                    MessageDialog.show(
                        "提示",
                        "设备当前时间:$time" + "\n" + "终端当前时间:${MyUtil.DateToStr(Date())}",
                        "确定"
                    ).maxWidth =
                        if (appContext.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) appContext.resources.displayMetrics.widthPixels / 2 else appContext.resources.displayMetrics.widthPixels
                    resetClickType()
                }

                6 -> {
                    viewModelScope.launch {
                        if (data[data.size - 2].toInt() == 0x5A) {

                            if (clearFlashIndex == 0) {
                                clearFlashIndex++
                                continueClear.value = true
                            } else if (clearFlashIndex == 1) {
                                ToastUtils.show("格式化存储区成功")
                                continueClear.value = false
                                closeWaitDialog.value = true
                                resetClickType()
                            }


                        } else if (data[data.size - 2].toInt() == 0xFF) {
                            ToastUtils.show("格式化存储区失败")
                            closeWaitDialog.value = true
                        }
                    }

                }

                7 -> {
                    var dataHex = MyUtil.bytes2Hex(data)
                    var flash2Size =
                        "" + (dataHex.substring(dataHex.length - 10, dataHex.length - 2).toInt(16)
                            .toDouble() / 1024.0) + " KB"
//                var flash2UsedSize =
//                    "" + (dataHex.substring(dataHex.length - 18, dataHex.length - 10).toInt(16)
//                        .toDouble() / 1024.0) + " KB"
                    var flash1Size =
                        "" + (dataHex.substring(dataHex.length - 26, dataHex.length - 18).toInt(16)
                            .toDouble() / 1024.0) + " KB"
//                var flash1UsedSize =
//                    "" + (dataHex.substring(dataHex.length - 34, dataHex.length - 26).toInt(16)
//                        .toDouble() / 1024.0) + " KB"
                    var totalSize =
                        "" + (dataHex.substring(dataHex.length - 42, dataHex.length - 34).toInt(16)
                            .toDouble() / 1024.0) + "KB"
                    var flash1TotalNumber =
                        (dataHex.substring(dataHex.length - 26, dataHex.length - 18).toInt(16) / 32)
                    var flash2TotalNumber =
                        (dataHex.substring(dataHex.length - 10, dataHex.length - 2).toInt(16) / 32)
                    var totalSizeCount =
                        (dataHex.substring(dataHex.length - 42, dataHex.length - 34).toInt(16) / 32)
                    MessageDialog.show(
                        "提示",
                        "存储总量:$totalSizeCount 条,\n存储区1已存储量：$flash1TotalNumber 条,\n存储区2已存储量：$flash2TotalNumber 条",
                        "确定"
                    ).maxWidth =
                        if (appContext.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) appContext.resources.displayMetrics.widthPixels / 2 else appContext.resources.displayMetrics.widthPixels
                    resetClickType()
                }

                15 -> {
                    var hexResult = MyUtil.bytes2Hex(data.copyOfRange(0, 3))
                    viewModelScope.launch {
                        if ("FF55AA" == hexResult) {
                            packageDataLength = 0
                            resultDataLength = MyUtil.bytes2Hex(data.copyOfRange(3, 5)).toInt(16)
                            dataResult = ByteArray(resultDataLength + 5)
                            needFoldData = data.size < resultDataLength + 5
                        }
                        if (needFoldData) {
                            System.arraycopy(data, 0, dataResult, packageDataLength, data.size)
                            packageDataLength += data.size
                            needFoldData = packageDataLength != resultDataLength + 5
                            if (packageDataLength == resultDataLength + 5) {
                                var packageData = dataResult.copyOfRange(0, dataResult.size - 1)
                                var result = CRC16Utils.checkCRC(packageData)

                                if (result.toInt(16) == java.lang.Byte.toUnsignedInt(dataResult[dataResult.size - 1])) {
                                    Log.e("设置的值", "设置的值     " + setedDeviceName)
                                    mmkv.putString(ValueKey.CURRENT_DEVICE_NAME, setedDeviceName)
                                    LiveDataEvent.showTitle.value = true
                                    MessageDialog.show(
                                        "提示", "设置成功", "确定"
                                    ).maxWidth =
                                        if (appContext.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) appContext.resources.displayMetrics.widthPixels / 2 else appContext.resources.displayMetrics.widthPixels
                                } else {
                                    ToastUtils.show("命令校验失败")
                                }

                            }
                        } else {
                            var packageData = data.copyOfRange(0, data.size - 1)
                            var result = CRC16Utils.checkCRC(packageData)
                            if (result.toInt(16) == java.lang.Byte.toUnsignedInt(data[data.size - 1])) {
                                Log.e("设置的值", "设置的值     " + setedDeviceName)
                                mmkv.putString(ValueKey.CURRENT_DEVICE_NAME, setedDeviceName)
                                LiveDataEvent.showTitle.value = true
                                MessageDialog.show(
                                    "提示", "设置成功", "确定"
                                ).maxWidth =
                                    if (appContext.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) appContext.resources.displayMetrics.widthPixels / 2 else appContext.resources.displayMetrics.widthPixels
                            } else {
                                ToastUtils.show("命令校验失败")
                            }
                        }
                        resetClickType()
                    }


                }

                16 -> {
                    viewModelScope.launch {
                        var hexResult = MyUtil.bytes2Hex(data.copyOfRange(0, 3))
                        if ("FF55AA" == hexResult) {
                            packageDataLength = 0
                            resultDataLength = MyUtil.bytes2Hex(data.copyOfRange(3, 5)).toInt(16)
                            dataResult = ByteArray(resultDataLength + 5)
                            needFoldData = data.size < resultDataLength + 5
                        }
                        if (needFoldData) {
                            System.arraycopy(data, 0, dataResult, packageDataLength, data.size)
                            packageDataLength += data.size
                            needFoldData = packageDataLength != resultDataLength + 5
                            if (packageDataLength == resultDataLength + 5) {
                                var packageData = dataResult.copyOfRange(0, dataResult.size - 1)
                                var result = CRC16Utils.checkCRC(packageData)

                                if (result.toInt(16) == java.lang.Byte.toUnsignedInt(dataResult[dataResult.size - 1])) {
                                    taskDeviceName =
                                        data.copyOfRange(14, 54).toString(Charsets.UTF_8).trim()
                                    showPopupwindow.value = true
                                    taskCurrentName = data.copyOfRange(54, 94)
                                    taskDesc = data.copyOfRange(94, 134)
                                } else {
                                    ToastUtils.show("命令校验失败")
                                }

                            }
                        } else {
                            var packageData = data.copyOfRange(0, data.size - 1)
                            var result = CRC16Utils.checkCRC(packageData)
                            if (result.toInt(16) == java.lang.Byte.toUnsignedInt(data[data.size - 1])) {
                                taskDeviceName =
                                    data.copyOfRange(14, 54).toString(Charsets.UTF_8).trim()
                                showPopupwindow.value = true
                                taskCurrentName = data.copyOfRange(54, 94)
                                taskDesc = data.copyOfRange(94, 134)
                            } else {
                                ToastUtils.show("命令校验失败")
                            }
                        }
                        resetClickType()
                    }


                }
            }
        }
    }

    fun handleWorkMode(data: ByteArray) {
        viewModelScope.launch {
            Log.e("clickType", "clickType  9999 " + MyUtil.bytes2Hex(data))
            //9600波特率会分包，拆成64和一个50多的坑人
            //460800波特率 每包数据最大就有490长度，就不会分包了
            Log.e("执行了这里", "执行了这里")
            var dataHex = MyUtil.bytes2Hex(data)
            var workMode = dataHex.substring(34, 36).toInt(16)//0:空闲模式 1：离线模式 3：在线模式

            otherPackageData = data.copyOfRange(14, 210)
            otherPackageData[3] = checkedWorkMode.toByte()
            Log.e("clickType", "存的其它数据 " + MyUtil.bytes2Hex(otherPackageData))


            if (HBluetooth.getInstance().isConnected) {
                HBluetooth.getInstance().sender()?.let { it1 ->
                    clickType = 10
                    var workModeVale = 0
                    var cmd = "FF55AA00D2" + getAddress() + "45020000000000C8" + MyUtil.bytes2Hex(
                        otherPackageData
                    ) + "00000000"
                    sendCommonCMD(
                        it1, cmd + CRC16Utils.checkCRC(MyUtil.hex2Bytes(cmd))
                    )

                }
            } else {
                ToastUtils.show("请先连接设备后再操作")
            }
        }
    }

    fun sendCommonCMD(mSender: Sender, value: String) {
        viewModelScope.launch {
            var bufData = MyUtil.hex2Bytes(value)
            Log.e("sendCommonCMD", "sendCommonCMD  : " + MyUtil.bytes2Hex(bufData))
            sendCmdWithOutTime(bufData)
        }
    }

    fun sendClearAllCMD(value: String) {
        viewModelScope.launch {
            var bufData = MyUtil.hex2Bytes(value)
            Log.e("sendClearAllCMD", "sendClearAllCMD  : " + MyUtil.bytes2Hex(bufData))
            HBluetooth.getInstance().sender().send(bufData, object : SendCallBack {
                override fun onSending(command: ByteArray) {
//                    addMessage("命令发送中... " + MyUtil.bytes2Hex(command))
                }

                override fun onSendFailure(bleException: BluetoothException) {
                    Log.e("onSendFailure", "onSendFailure " + bleException.message.toString())
                }
            })
        }
    }

    fun sendCmdWithOutTime(bufData: ByteArray) {
        HBluetooth.getInstance().sender().send(bufData, object : SendCallBack {
            override fun onSending(command: ByteArray) {
//                    addMessage("命令发送中... " + MyUtil.bytes2Hex(command))
            }

            override fun onSendFailure(bleException: BluetoothException) {
                Log.e("onSendFailure", "onSendFailure " + bleException.message.toString())
            }
        })
        viewModelScope.launch {
            val conditionIsTrue = withTimeoutOrNull(3000L) {
                repeat(3) { index ->
                    if (clickType == -1) {
                        return@withTimeoutOrNull true
                    }
                    delay(1000L)
                }
                false
            }
            conditionIsTrue?.let { isTrue ->
                Log.e(
                    "sendCmdWithOutTime", "最终条件是: $isTrue"
                )
            } ?: run {
                ToastUtils.show(appContext.resources.getString(R.string.out_time_tips))
                Log.e(
                    "sendCmdWithOutTime", "等待时间超时，未满足条件"
                )
            }
        }
    }

    public fun queryTaskCMD() {
        if (HBluetooth.getInstance().isConnected) {
            HBluetooth.getInstance().sender()?.let { it1 ->
                clickType = 16
                var cmd = "FF55AA000A" + getAddress() + "4501000010300078"

                sendCommonCMD(
                    it1, cmd + CRC16Utils.checkCRC(MyUtil.hex2Bytes(cmd))
                )
            }
        } else {
            ToastUtils.show("请先连接设备后再操作")
        }
    }

    private fun formatTimeString(time: String): String {
        var result = ""
        var year = "" + (2000 + time.substring(0, 2).toInt(16))
        var month = time.substring(2, 4).toInt(16)
        var day = time.substring(4, 6).toInt(16)
        var hour = time.substring(6, 8).toInt(16)
        var minute = time.substring(8, 10).toInt(16)
        var second = time.substring(10, 12).toInt(16)
        result = year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second
        return MyUtil.DateToStr(MyUtil.StrToDate(result))
    }

    fun getAddress(): String {
        return "FA"
    }

    public fun resetClickType() {
        clickType = -1
    }


    suspend fun checkFirUpdate(isRefresh: Boolean, loadingXml: Boolean = false) {
        mAppUpdateEntity.value = RxHttp.get("http://api.bq04.com/apps/latest/" + "65a65a36b2eb46511afcecc4")
            .add("api_token", "e7fd98786076f67c0795084a5738e608").toAwait<AppUpdateBean>().await()
    }


}


